package org.sgx.gwtsjcl.client;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArrayInteger;

/**
 * sjcl.random - Random number generator
 * 
 * <p>
 * This random number generator is a derivative of Ferguson and Schneier's generator Fortuna. It collects entropy from various events into several pools, implemented by streaming
 * SHA-256 instances. It differs from ordinary Fortuna in a few ways, though.
 * </p>
 * 
 * <p>
 * Most importantly, it has an entropy estimator. This is present because there is a strong conflict here between making the generator available as soon as possible, and making
 * sure that it doesn't "run on empty". In Fortuna, there is a saved state file, and the system is likely to have time to warm up.
 * </p>
 * 
 * <p>
 * Second, because users are unlikely to stay on the page for very long, and to speed startup time, the number of pools increases logarithmically: a new pool is created when the
 * previous one is actually used for a reseed. This gives the same asymptotic guarantees as Fortuna, but gives more entropy to early reseeds.
 * </p>
 * 
 * <p>
 * The entire mechanism here feels pretty klunky. Furthermore, there are several improvements that should be made, including support for dedicated cryptographic functions that may
 * be present in some browsers; state files in local storage; cookies containing randomness; etc. So look for improvements in future versions.
 * </p>
 * 
 * @author sg
 * 
 */
public class Random extends JavaScriptObject {
	protected Random() {
	}

	/**
	 * Add entropy to the pools. 
	 * @param data The entropic value. Should be a 32-bit integer, array of 32-bit integers, or string
	 * @param estimatedEntropy The estimated entropy of data, in bits
	 * @param source The source of the entropy, eg "mouse"
	 * @return
	 */
	public native final void addEntropy(int data, int estimatedEntropy, String source)/*-{
		this.addEntropy(data, estimatedEntropy, source);
	}-*/;
	
//	/**
//	 * Add entropy to the pools. 
//	 * @param data The entropic value. Should be a 32-bit integer, array of 32-bit integers, or string
//	 * @param estimatedEntropy The estimated entropy of data, in bits
//	 * @param source The source of the entropy, eg "mouse"
//	 * @return
//	 */
//	public native final void addEntropy(int data, int estimatedEntropy)/*-{
//		this.addEntropy(data, estimatedEntropy);
//	}-*/;
	
	
	/**
	 * Generate several random words, and return them in an array 
	 * @param nwords
	 * @param paranoia
	 * @return
	 */
	public native final JsArrayInteger randomWords(int nwords, int paranoia)/*-{
		return this.randomWords(nwords, paranoia);
	}-*/;
	
	/**
	 * Generate several random words, and return them in an array 
	 * @param nwords
	 * @return
	 */
	public native final JsArrayInteger randomWords(int nwords)/*-{
		return this.randomWords(nwords, 0);
	}-*/;
	
	
	public native final void startCollectors()/*-{
		return this.startCollectors(); 
	}-*/;
	
	public native final void stopCollectors()/*-{
	return this.stopCollectors(); 
}-*/;
	
	
}
